/**
 * Copyright (c) 2019-2021,  陈俊兵 (cjb6b.com@gmail.com)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ktjiaoyu.thread.sync;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @packageName com.ktjiaoyu.thread.sync
 * @fileName SynchronizedTest.java
 * @author 陈俊兵 (cjb6b.com@gmail.com)
 * @createTime 2023/7/24 21:12
 * @lastModify 2023/7/24 21:12
 * @version 1.0.0
 */
public class SynchronizedTest {

    public static void main(String[] args) {
        // 锁对象
        Object lock = new Object();

//        synchronized (lock){
//            // 临界区代码1
//            System.out.println("进入了第一道门");
//            synchronized (lock){
//                // 临界区代码2
//                System.out.println("进入了第二道门");
//            }
//        }
        Thread t1 = new Thread(()->{
            synchronized (lock){
                System.out.println(Thread.currentThread().getName() + "拿到了锁！");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "释放了锁！");

                // 演示非公平锁
                for (int i = 0; i < 10; i++) {
                    new Thread(()->{
                        synchronized (lock){
                            System.out.println(Thread.currentThread().getName() + "拿到了锁！");
                        }
                    }, "抢锁线程" + (i + 1)).start();
                }
            }
        });
        t1.start();
        try {
            // 保证t1先拿到锁
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        final List<Thread> threads = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            final int fi = i;
            Thread now = new Thread(()->{
                if(fi != 0){
                    // 循环判断上一个线程是否处于阻塞与锁的状态
                    while(threads.get(fi - 1).getState() != Thread.State.BLOCKED){
                        try {
                            Thread.sleep(0);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                System.out.println(Thread.currentThread().getName() + "准备拿锁！");
                synchronized (lock){
                    System.out.println(Thread.currentThread().getName() + "拿到了锁！");
                }
            }, "线程" + (i + 1));
            now.start();
            threads.add(now);
        }

    }
}
